home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Applications
/
PICSee Dust 1.01
/
Primary Source
/
PICSViewerSelection.cpp
< prev
Wrap
C/C++ Source or Header
|
1995-11-23
|
13KB
|
477 lines
#include "PICSViewerPrivate.h"
#include "Marquee.h"
#include "assert_mac.h"
#include "KeyUtils.h"
// ---------------------------------------------------------------------------
static RGBColor sMarqueeColor;
// ---------------------------------------------------------------------------
static void _ResizePICSViewerSelection(PICSViewerData *viewer, const Rect *newMarquee);
static void _MovePICSViewerSelection(
PICSViewerData *viewer,
Point mouseLoc,
short offsetH,
short offsetV);
#define MARQUEE_DELAY 2
// ---------------------------------------------------------------------------
void _SetMarqueeColor(RGBColor *marqueeColor) {
sMarqueeColor = *marqueeColor;
} // END _SetMarqueeColor
// ---------------------------------------------------------------------------
/*
This is the callback routine that is called constantly when
the user is sizing or dragging the marquee.
*/
void _TrackUpdateMarquee(const Rect *rectToUpdate, const Rect *currentMarquee) {
PICSViewerData *viewer;
viewer = _ExtractPICSViewer(FrontWindow());
if (viewer == NULL) {
SysBeep(10);
ASSERT(viewer != NULL);
}
else {
_EraseMarquee(viewer, rectToUpdate);
_SetMarqueeRect(viewer, currentMarquee, true);
}
} // END _UpdateMouseMarquee
// ---------------------------------------------------------------------------
/*
This erases the marquee by CopyBitsing() from the offscreen
buffer to <rectToErase>. If you pass NULL to <rectToErase>,
it will use the current marquee's rect.
*/
void _EraseMarquee(PICSViewerData *viewer, const Rect *rectToErase) {
Rect srcDrawRect, destDrawRect;
RGBColor saveBack, backColor;
if (rectToErase != NULL)
destDrawRect = *rectToErase;
else
destDrawRect = viewer->marqueeRect;
if (EmptyRect(&destDrawRect))
return;
srcDrawRect = destDrawRect;
OffsetRect(&srcDrawRect, -viewer->outputFrame.left,
-viewer->outputFrame.top);
// Map src rect to correct frame in viewer->buffer
OffsetRect(&srcDrawRect, 0, viewer->curFrame *
viewer->picsFrame.bottom);
GetBackColor(&saveBack);
backColor.red = backColor.green = backColor.blue = 0xFFFF;
RGBBackColor(&backColor);
CopyGraphicsBuffer2Window(viewer->buffer, viewer->window,
(CP_Rect*)&srcDrawRect, (CP_Rect*)&destDrawRect);
RGBBackColor(&saveBack);
} // END _EraseMarquee
// ---------------------------------------------------------------------------
/*
Call this to set the rect of the marquee. The marquee is not
drawn, however. Call _FrameMarquee() to do that.
If you pass NULL to <newMarquee> it sets the marquee rect
to empty (0,0,0,0)
*/
void _SetMarqueeRect(
PICSViewerData *viewer,
const Rect *newMarquee,
Boolean updateInfo) {
if (EqualRect(newMarquee, &viewer->marqueeRect)) {
return;
}
if (newMarquee != NULL)
viewer->marqueeRect = *newMarquee;
else
SetRect(&viewer->marqueeRect, 0, 0, 0, 0);
if (updateInfo)
_UpdateMarqueeRectInfo(viewer);
} // END _SetMarqueeRect
// ---------------------------------------------------------------------------
/*
This gives pertinent info on the marquee...
*/
void _UpdateMarqueeRectInfo(PICSViewerData *viewer) {
Str255 outputStr = "\p[ Left: ";
Str15 topStr = "\p | Top: ";
Str15 rightStr = "\p | Right: ";
Str15 bottomStr = "\p | Bottom: ";
Str15 widthStr = "\p | W: ";
Str15 heightStr = "\p | H: ";
Str15 endStr = "\p ]";
Str15 numStr;
Rect marqueeRect;
marqueeRect = viewer->marqueeRect;
// Compensate for viewer->outputFrame
OffsetRect(&marqueeRect, -viewer->outputFrame.left,
-viewer->outputFrame.top);
NumToString(marqueeRect.left, numStr);
PStrCat(numStr, outputStr);
PStrCat(topStr, outputStr);
NumToString(marqueeRect.top, numStr);
PStrCat(numStr, outputStr);
PStrCat(rightStr, outputStr);
NumToString(marqueeRect.right, numStr);
PStrCat(numStr, outputStr);
PStrCat(bottomStr, outputStr);
NumToString(marqueeRect.bottom, numStr);
PStrCat(numStr, outputStr);
PStrCat(widthStr, outputStr);
NumToString(marqueeRect.right - marqueeRect.left, numStr);
PStrCat(numStr, outputStr);
PStrCat(heightStr, outputStr);
NumToString(marqueeRect.bottom - marqueeRect.top, numStr);
PStrCat(numStr, outputStr);
PStrCat(endStr, outputStr);
SetDItemText(viewer->window,
kPICSViewer_TrackCropField, outputStr);
} // END _UpdateMarqueeRectInfo
// ---------------------------------------------------------------------------
/*
Either select everything or deselect everything.
*/
void _SelectEntirePICSViewerFrame(PICSViewerData *viewer, Boolean select) {
if (!viewer->trackMouse) {
SetDlogCtlValue(viewer->window, kPICSViewer_TrackMouseBtn, 1);
viewer->trackMouse = true;
}
if (select) {
_SetMarqueeRect(viewer, &viewer->outputFrame, true);
}
else {
_SetMarqueeRect(viewer, NULL, false);
SetDItemText(viewer->window, kPICSViewer_TrackCropField, kEmptyStr);
}
// Erase old marquee frame; idle proc will draw
// new marquee
_EraseMarquee(viewer, &viewer->outputFrame);
}
// ---------------------------------------------------------------------------
void _ActionPICSViewer(PICSViewerData *viewer) {
if (viewer->trackMouse) {
Point mouseLoc;
Boolean validTrackRect;
Boolean insideTrackRect;
// Is there a marquee?
validTrackRect = !EmptyRect(&viewer->marqueeRect);
// If marquee exists, is mouse inside it?
GetMouse(&mouseLoc);
if (validTrackRect)
insideTrackRect = PtInRect(mouseLoc, &viewer->marqueeRect);
else
insideTrackRect = false;
switch(viewer->currentAction) {
case kSelectionAction: {
// Standard mouse click with no modifier keys pressed
// Erase current marquee, if any
if (validTrackRect) {
_EraseMarquee(viewer, NULL);
_SetMarqueeRect(viewer, NULL, false);
}
SetPort(viewer->window);
GetMouse(&mouseLoc);
if (PtInRect(mouseLoc, &viewer->outputFrame)) {
// Anchor coordinates of topleft of
// tracking rect first before calling
// TrackMarquee.
TrackMarqueeOpaque(mouseLoc,
(TrackUpdateProc)_TrackUpdateMarquee, &sMarqueeColor,
&viewer->outputFrame, &viewer->marqueeRect);
}
if (EmptyRect(&viewer->marqueeRect)) {
SetDItemText(viewer->window,
kPICSViewer_TrackCropField, kEmptyStr);
}
} break;
case kCompositeAction: {
if (insideTrackRect) {
SetCursor(&qd.arrow);
_CompositePICSViewer(viewer);
}
} break;
case kLeftAdjustSelectionAction:
case kRightAdjustSelectionAction: {
long dummy;
Rect adjustedRect = viewer->marqueeRect;
while (StillDown()) {
GetMouse(&mouseLoc);
_EraseMarquee(viewer, NULL);
ConstrainPointWithinRect(&mouseLoc, &viewer->outputFrame);
if (viewer->currentAction == kLeftAdjustSelectionAction) {
if (mouseLoc.h >= adjustedRect.right) {
mouseLoc.h = adjustedRect.right - 1;
}
adjustedRect.left = mouseLoc.h;
}
else {
if (mouseLoc.h <= adjustedRect.left) {
mouseLoc.h = adjustedRect.left + 1;
}
adjustedRect.right = mouseLoc.h;
}
FrameMarquee(&adjustedRect, &sMarqueeColor);
_SetMarqueeRect(viewer, &adjustedRect, true);
Delay(MARQUEE_DELAY, &dummy);
}
} break;
case kTopAdjustSelectionAction:
case kBottomAdjustSelectionAction: {
long dummy;
Rect adjustedRect = viewer->marqueeRect;
while (StillDown()) {
GetMouse(&mouseLoc);
_EraseMarquee(viewer, NULL);
ConstrainPointWithinRect(&mouseLoc, &viewer->outputFrame);
if (viewer->currentAction == kTopAdjustSelectionAction) {
if (mouseLoc.v >= adjustedRect.bottom) {
mouseLoc.v = adjustedRect.bottom - 1;
}
adjustedRect.top = mouseLoc.v;
}
else {
if (mouseLoc.v <= adjustedRect.top) {
mouseLoc.v = adjustedRect.top + 1;
}
adjustedRect.bottom = mouseLoc.v;
}
FrameMarquee(&adjustedRect, &sMarqueeColor);
_SetMarqueeRect(viewer, &adjustedRect, true);
Delay(MARQUEE_DELAY, &dummy);
}
} break;
case kMoveSelectionAction: {
long dummy;
Rect dragRect = viewer->marqueeRect;
short offsetH, offsetV;
if (insideTrackRect) {
SetCursor(*GetCursor(kHandClosedCursorID));
// Assumes mouse is INSIDE tracking rect
// & thus to right & below of topLeft of rect
offsetH = mouseLoc.h - viewer->marqueeRect.left;
offsetV = mouseLoc.v - viewer->marqueeRect.top;
while (StillDown()) {
GetMouse(&mouseLoc);
_MovePICSViewerSelection(viewer, mouseLoc,
offsetH, offsetV);
Delay(MARQUEE_DELAY, &dummy);
}
if (EmptyRect(&viewer->marqueeRect)) {
SetDItemText(viewer->window,
kPICSViewer_TrackCropField, kEmptyStr);
}
}
} break;
case kNoAction:
// Mouse click in gray area. De-select marquee
if (validTrackRect) {
_EraseMarquee(viewer, NULL);
_SetMarqueeRect(viewer, NULL, true);
SetDItemText(viewer->window,
kPICSViewer_TrackCropField, kEmptyStr);
}
break;
}
}
} // END _ActionPICSViewer
// ---------------------------------------------------------------------------
void _MovePICSViewerSelection(
PICSViewerData *viewer,
Point mouseLoc,
short offsetH,
short offsetV) {
Rect moveRect = viewer->marqueeRect;
_EraseMarquee(viewer, NULL);
ConstrainPointWithinRect(&mouseLoc, &viewer->outputFrame);
MoveRectTo(&moveRect,
mouseLoc.h-offsetH, mouseLoc.v-offsetV);
// Confine marquee to outputFrame
if (moveRect.left < viewer->outputFrame.left) {
OffsetRect(&moveRect, (viewer->outputFrame.left -
moveRect.left), 0);
}
else if (moveRect.right > viewer->outputFrame.right) {
OffsetRect(&moveRect, (viewer->outputFrame.right -
moveRect.right), 0);
}
if (moveRect.top < viewer->outputFrame.top) {
OffsetRect(&moveRect, 0, (viewer->outputFrame.top -
moveRect.top));
}
else if (moveRect.bottom > viewer->outputFrame.bottom) {
OffsetRect(&moveRect, 0, (viewer->outputFrame.bottom -
moveRect.bottom));
}
if (EmptyRect(&moveRect)) {
// Could be "negative space" rect, so clear it
SetRect(&moveRect, 0, 0, 0, 0);
}
FrameMarquee(&moveRect, &sMarqueeColor);
_SetMarqueeRect(viewer, &moveRect, true);
} // END _MovePICSViewerSelection
// ---------------------------------------------------------------------------
void _ResizePICSViewerSelection(PICSViewerData *viewer, const Rect *newMarquee) {
_EraseMarquee(viewer, NULL);
FrameMarquee(newMarquee, &sMarqueeColor);
_SetMarqueeRect(viewer, newMarquee, true);
} // END _ResizePICSViewerSelection
// ---------------------------------------------------------------------------
void _KeyDownPICSViewerSelection(PICSViewerData *viewer, char keyPressed) {
Rect adjustedRect = viewer->marqueeRect;
if (SHRINKSELECTION_SHORTCUT) {
switch(keyPressed) {
case kLeftArrow_Key:
adjustedRect.right--;
if (adjustedRect.right <= adjustedRect.left)
adjustedRect.right = adjustedRect.left + 1;
break;
case kRightArrow_Key:
adjustedRect.left++;
if (adjustedRect.left >= adjustedRect.right)
adjustedRect.left = adjustedRect.right - 1;
break;
case kUpArrow_Key:
adjustedRect.bottom--;
if (adjustedRect.bottom <= adjustedRect.top)
adjustedRect.bottom = adjustedRect.top + 1;
break;
case kDownArrow_Key:
adjustedRect.top++;
if (adjustedRect.top >= adjustedRect.bottom)
adjustedRect.top = adjustedRect.bottom - 1;
break;
}
_ResizePICSViewerSelection(viewer, &adjustedRect);
}
else if (GROWSELECTION_SHORTCUT) {
switch(keyPressed) {
case kLeftArrow_Key:
adjustedRect.left--;
break;
case kRightArrow_Key:
adjustedRect.right++;
break;
case kUpArrow_Key:
adjustedRect.top--;
break;
case kDownArrow_Key:
adjustedRect.bottom++;
break;
}
// Keep new marquee within bounds of PICS
if (adjustedRect.left < viewer->outputFrame.left)
adjustedRect.left = viewer->outputFrame.left;
if (adjustedRect.right > viewer->outputFrame.right)
adjustedRect.right = viewer->outputFrame.right;
if (adjustedRect.top < viewer->outputFrame.top)
adjustedRect.top = viewer->outputFrame.top;
if (adjustedRect.bottom > viewer->outputFrame.bottom)
adjustedRect.bottom = viewer->outputFrame.bottom;
_ResizePICSViewerSelection(viewer, &adjustedRect);
}
else {
short increment;
Point movedPoint;
if (!LARGERINCREMENT_SHORTCUT)
increment = kUsualMoveIncrement;
else
increment = kLargerMoveIncrement;
switch(keyPressed) {
case kLeftArrow_Key:
OffsetRect(&adjustedRect, -increment, 0);
break;
case kRightArrow_Key:
OffsetRect(&adjustedRect, increment, 0);
break;
case kUpArrow_Key:
OffsetRect(&adjustedRect, 0, -increment);
break;
case kDownArrow_Key:
OffsetRect(&adjustedRect, 0, increment);
break;
} // END inner switch
movedPoint.h = adjustedRect.left;
movedPoint.v = adjustedRect.top;
_MovePICSViewerSelection(viewer, movedPoint, 0, 0);
}
}
// ---------------------------------------------------------------------------
void _FrameMarquee(PICSViewerData *viewer) {
FrameMarquee(&viewer->marqueeRect, &sMarqueeColor);
} // END _FrameMarquee